package com.atguigu.day3;

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.TimeUnit;

public class BlockingQueueDemo {
    public static void main(String[] args) throws InterruptedException {
        //创建一个3个坑位的数组有界队列
        BlockingQueue<String> blockingQueue = new ArrayBlockingQueue<>(3);

        //抛出异常 插入add(e)    移除remove()    检查（获取）element()只会获取顶部的值
        /*System.out.println(blockingQueue.add("a"));
        System.out.println(blockingQueue.add("b"));
        System.out.println(blockingQueue.add("c"));
        //添加数大于坑位数会【抛异常】
        //Exception in thread "main" java.lang.IllegalStateException: Queue full
        //System.out.println(blockingQueue.add("d"));
        System.out.println(blockingQueue.element());
        System.out.println(blockingQueue.remove());
        System.out.println(blockingQueue.element());
        System.out.println(blockingQueue.remove());
        System.out.println(blockingQueue.element());
        System.out.println(blockingQueue.remove());
        //移除数大于实际存在的数量会【抛异常】
        //Exception in thread "main" java.util.NoSuchElementException
        //System.out.println(blockingQueue.remove());
        //当队列为空的时候获取队列的值会【抛异常】
        //Exception in thread "main" java.util.NoSuchElementException
        //System.out.println(blockingQueue.element());*/

        //特殊值   offer(e)    poll()  peek()只会获取顶部的值
        /*System.out.println(blockingQueue.offer("a"));
        System.out.println(blockingQueue.offer("b"));
        System.out.println(blockingQueue.offer("c"));
        //当添加数大于坑数位，会报false
        //System.out.println(blockingQueue.offer("d"));
        System.out.println(blockingQueue.peek());
        System.out.println(blockingQueue.poll());
        System.out.println(blockingQueue.peek());
        System.out.println(blockingQueue.poll());
        System.out.println(blockingQueue.peek());
        System.out.println(blockingQueue.poll());
        //当队列移除把元素移除完之后再获取顶部的数值会报null
        System.out.println(blockingQueue.peek());
        //当队列元素移除完之后，再移除将会报null
        System.out.println(blockingQueue.poll());*/

        //阻塞    put(e)  take()
        /*blockingQueue.put("a");
        blockingQueue.put("b");
        blockingQueue.put("c");
        //当添加大于队列坑位，线程就一直阻塞在此，等待有坑位空出来
        //blockingQueue.put("x");
        System.out.println("------come in");

        System.out.println(blockingQueue.take());
        System.out.println(blockingQueue.take());
        System.out.println(blockingQueue.take());
        //当阻塞队列取完之后，再次调取take方法，线程会一直等待，只到队列添入新的元素
        System.out.println(blockingQueue.take());*/
        /**
         * "main" Id=1 WAITING on java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject@1562d8f3
         *     at java.base@17.0.7/jdk.internal.misc.Unsafe.park(Native Method)
         *     -  waiting on java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject@1562d8f3
         *     at java.base@17.0.7/java.util.concurrent.locks.LockSupport.park(LockSupport.java:341)
         *     at java.base@17.0.7/java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionNode.block(AbstractQueuedSynchronizer.java:506)
         *     at java.base@17.0.7/java.util.concurrent.ForkJoinPool.unmanagedBlock(ForkJoinPool.java:3463)
         *     at java.base@17.0.7/java.util.concurrent.ForkJoinPool.managedBlock(ForkJoinPool.java:3434)
         *     at java.base@17.0.7/java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:1623)
         *     at java.base@17.0.7/java.util.concurrent.ArrayBlockingQueue.put(ArrayBlockingQueue.java:370)
         *     at com.atguigu.day3.BlockingQueueDemo.main(BlockingQueueDemo.java:52)
         *     at java.base@17.0.7/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
         *     at java.base@17.0.7/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
         *     at java.base@17.0.7/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
         *     at java.base@17.0.7/java.lang.reflect.Method.invoke(Method.java:568)
         *     at app/jdk.compiler@17.0.7/com.sun.tools.javac.launcher.Main.execute(Main.java:419)
         *     at app/jdk.compiler@17.0.7/com.sun.tools.javac.launcher.Main.run(Main.java:192)
         *     at app/jdk.compiler@17.0.7/com.sun.tools.javac.launcher.Main.main(Main.java:132)
         *
         *
         * 	这是一个Java线程堆栈跟踪，显示了一个名为"main"的线程正在等待将元素放入一个ArrayBlockingQueue。ArrayBlockingQueue是一个有界阻塞队列，当队列满时，尝试插入元素的线程将被阻塞，直到队列中有空间可用。
         *
         * 	在这个堆栈跟踪中，我们可以看到以下关键信息：
         *
         * 	线程ID为1，状态为WAITING。
         * 	线程正在等待将元素放入ArrayBlockingQueue。
         * 	线程在java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject类的await方法上被阻塞。
         * 	线程在java.util.concurrent.ArrayBlockingQueue类的put方法上被阻塞。
         * 	线程所在的类是com.atguigu.day3.BlockingQueueDemo，位于BlockingQueueDemo.java文件的第52行。
         * 	总之，这个堆栈跟踪显示了一个线程在尝试将元素放入一个有界阻塞队列时被阻塞的情况。
         *
         *
         * "main" Id=1 WAITING on java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject@1051784
         *     at java.base@17.0.7/jdk.internal.misc.Unsafe.park(Native Method)
         *     -  waiting on java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject@1051784
         *     at java.base@17.0.7/java.util.concurrent.locks.LockSupport.park(LockSupport.java:341)
         *     at java.base@17.0.7/java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionNode.block(AbstractQueuedSynchronizer.java:506)
         *     at java.base@17.0.7/java.util.concurrent.ForkJoinPool.unmanagedBlock(ForkJoinPool.java:3463)
         *     at java.base@17.0.7/java.util.concurrent.ForkJoinPool.managedBlock(ForkJoinPool.java:3434)
         *     at java.base@17.0.7/java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:1623)
         *     at java.base@17.0.7/java.util.concurrent.ArrayBlockingQueue.take(ArrayBlockingQueue.java:420)
         *     at com.atguigu.day3.BlockingQueueDemo.main(BlockingQueueDemo.java:59)
         *     at java.base@17.0.7/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
         *     at java.base@17.0.7/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
         *     at java.base@17.0.7/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
         *     at java.base@17.0.7/java.lang.reflect.Method.invoke(Method.java:568)
         *     at app/jdk.compiler@17.0.7/com.sun.tools.javac.launcher.Main.execute(Main.java:419)
         *     at app/jdk.compiler@17.0.7/com.sun.tools.javac.launcher.Main.run(Main.java:192)
         *     at app/jdk.compiler@17.0.7/com.sun.tools.javac.launcher.Main.main(Main.java:132)
         *
         *
         * 	这是一个Java线程堆栈跟踪，显示了一个名为"main"的线程正在等待从ArrayBlockingQueue中取出元素。ArrayBlockingQueue是一个有界阻塞队列，当队列为空时，尝试取出元素的线程将被阻塞，直到队列中有元素可用。
         *
         * 	在这个堆栈跟踪中，我们可以看到以下关键信息：
         *
         * 	线程ID为1，状态为WAITING。
         * 	线程正在等待从ArrayBlockingQueue中取出元素。
         * 	线程在java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject类的await方法上被阻塞。
         * 	线程在java.util.concurrent.ArrayBlockingQueue类的take方法上被阻塞。
         * 	线程所在的类是com.atguigu.day3.BlockingQueueDemo，位于BlockingQueueDemo.java文件的第59行。
         * 	总之，这个堆栈跟踪显示了一个线程在尝试从有界阻塞队列中取出元素时被阻塞的情况
         */

        //混合使用，依然可以
        /*System.out.println(blockingQueue.add("A"));
        System.out.println(blockingQueue.element());
        System.out.println(blockingQueue.poll());
        System.out.println(blockingQueue.element());*/

        //超时    offer(e, time, unit)    poll(time, unit)
        System.out.println(blockingQueue.offer("a",1,TimeUnit.SECONDS));
        System.out.println(blockingQueue.offer("b",1,TimeUnit.SECONDS));
        System.out.println(blockingQueue.offer("c",1,TimeUnit.SECONDS));
        //当队列满的情况下，会根据时间和时间单位来决定等待的时间，当时间到达，依然没有空位线程会结束并返回false
        System.out.println(blockingQueue.offer("d",1,TimeUnit.SECONDS));
        System.out.println(blockingQueue.poll());
        System.out.println(blockingQueue.poll());
        System.out.println(blockingQueue.poll());
        //当队列全部移除完，再次调用移除功能，会根据时间和时间单位来决定等待的时间，当时间到达，队列没有进入新的线程，线程会结束，返回null
        System.out.println(blockingQueue.poll(1,TimeUnit.SECONDS));

    }
}
